package io.github.junxworks.qt.modules.tushare.service.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Maps;

import io.github.junxworks.qt.modules.data.service.DataStoreService;
import io.github.junxworks.qt.modules.data.vo.DStockProfileVo;
import io.github.junxworks.qt.modules.tushare.Fields;
import io.github.junxworks.qt.modules.tushare.TushareAPIs;
import io.github.junxworks.qt.modules.tushare.entity.DStockCompany;
import io.github.junxworks.qt.modules.tushare.entity.DStockConcept;
import io.github.junxworks.qt.modules.tushare.entity.DStockConceptDetail;
import io.github.junxworks.qt.modules.tushare.entity.DStockIndexClassify;
import io.github.junxworks.qt.modules.tushare.entity.DStockIndexMember;
import io.github.junxworks.qt.modules.tushare.entity.DStockProfile;
import io.github.junxworks.qt.modules.tushare.entity.DStockStkRewards;
import io.github.junxworks.qt.modules.tushare.mapper.BaseInfoMapper;
import io.github.junxworks.qt.modules.tushare.service.BaseInfoService;
import io.github.junxworks.qt.modules.tushare.service.TushareService;
import io.github.junxworks.qt.utils.BatchUtils;

// TODO: Auto-generated Javadoc
/**
 * The Class BaseInfoServiceImpl.
 *
 * @program :springbootdev
 * @description: 
 * @author:Junxworks 
 * @create:2019-08-16 19:51
 */
@Service("TushareBaseInfoService")
public class TushareBaseInfoService extends TushareService {

	/** The data store service. */
	@Autowired
	private DataStoreService dataStoreService;

	/** The base info mapper. */
	@Autowired
	private BaseInfoMapper baseInfoMapper;

	@Autowired
	private BaseInfoService baseInfoService;

	/**
	 * 更新股票最新数据.
	 */
	public void fetchStockProfiles() {
		saveProfile("L");
		saveProfile("D");
		saveProfile("P");
		baseInfoService.refreshStockProfilesCache();
	}

	/**
	 * Save profile.
	 *
	 * @param status the status
	 */
	private void saveProfile(String status) {
		Map<String, String> params = Maps.newHashMap();
		params.put("list_status", status);
		consumeTushareData(TushareAPIs.BASE_STOCK, Fields.F_BASE, DStockProfile.class, params, l -> {
			if (!l.isEmpty()) {
				baseInfoMapper.clearStockProfiles(status);
				dataStoreService.insertBatch(l);
			}
		});
	}

	public void fetchStockCompanies() {
		fetchCompanyInfo("SSE"); //上交所
		fetchCompanyInfo("SZSE"); //深交所
		fetchCompanyInfo("BSE"); //北交所
	}

	/**
	 * 获取上市公司基础信息
	 * @param exchange 交易所代码 ，SSE上交所 SZSE深交所 BSE北交所
	 */
	private void fetchCompanyInfo(String exchange) {
		Map<String, String> params = Maps.newHashMap();
		params.put("exchange", exchange);
		consumeTushareData(TushareAPIs.BASE_COMPANY, Fields.F_STOCK_COMPANY, DStockCompany.class, params, l -> {
			if (!l.isEmpty()) {
				baseInfoMapper.clearStockCompanyInfo(exchange);
				dataStoreService.insertBatch(l);
			}
		});
	}

	@Deprecated
	public void fetchStockConcept() {
		consumeTushareData(TushareAPIs.BASE_CONCEPT, Fields.F_CONCEPT, DStockConcept.class, Maps.newHashMap(), l -> {
			if (!l.isEmpty()) {
				baseInfoMapper.deleteStockConcept();
				dataStoreService.insertBatch(l);
			}
		});
	}

	@Deprecated
	public void fetchStockConceptDetail() {
		List<String> concepts = baseInfoMapper.queryAllStockConcept();
		consumeTushareDataOneByOne(TushareAPIs.BASE_CONCEPT_DETAIL, Fields.F_CONCEPT_DETAIL, DStockConceptDetail.class, Maps.newHashMap(), 0, "id", () -> {
			return concepts;
		}, l -> {
			if (!l.isEmpty()) {
				DStockConceptDetail d = l.get(0);
				baseInfoMapper.deleteStockConceptDetailByConceptId(d.getId());
				dataStoreService.insertBatch(l);
			}
		});
		baseInfoMapper.clearConceptUseful();
		dataStoreService.insertBatch(baseInfoMapper.selectConceptUsefulData());
	}

	public void collectStockIndexClassify() {
		Map<String, String> params = Maps.newHashMap();
		params.put("src", "SW2021");
		consumeTushareData(TushareAPIs.BASE_INDEX_CLASSIFY, Fields.F_INDEX_CLASSIFY, DStockIndexClassify.class, params, l -> {
			if (!l.isEmpty()) {
				baseInfoMapper.deleteStockIndexClassify();
				dataStoreService.insertBatch(l);
			}
		});
		collectStockIndexMember();
	}

	public void collectStockIndexMember() {
		consumeTushareDataOneByOne(TushareAPIs.BASE_INDEX_MEMBER, Fields.F_INDEX_MEMBER, DStockIndexMember.class, Maps.newHashMap(), 0, "index_code", () -> {
			return baseInfoMapper.queryAllStockIndexClassifyCode();
		}, l -> {
			if (!l.isEmpty()) {
				DStockIndexMember d = l.get(0);
				baseInfoMapper.deleteStockIndexMember(d.getIndexCode());
				dataStoreService.insertBatch(l);
			}
		});
	}

	public void fetchStkRewardsData(String endDate) {
		handleDataByLastFinanceReportPeriod(endDate, date -> {
			handleFetchStkRewardsData(date);
		});
	}

	public void fetchStkRewardsDataByRange(String periodRange) {
		handleDataByLastFinanceReportPeriodRange(periodRange, date -> {
			handleFetchStkRewardsData(date);
		});
	}

	private void handleFetchStkRewardsData(String endDate) {
		baseInfoMapper.clearStkRewardsByEndDate(endDate);
		Map<String, String> params = Maps.newHashMap();
		params.put("end_date", endDate);
		List<DStockProfileVo> stocks = baseInfoMapper.selectStockProfileBefore(endDate);
		BatchUtils.batchHandle(stocks, 900, sl -> {
			StringBuilder sb = new StringBuilder();
			sl.forEach(s -> {
				sb.append(s.getTsCode()).append(",");
			});
			params.put("ts_code", sb.toString().substring(0, sb.length() - 1));
			consumeTushareData(TushareAPIs.BASE_STK_REWARDS, Fields.F_STK_REWARDS, DStockStkRewards.class, params, l -> {
				if (!l.isEmpty()) {
					dataStoreService.insertBatch(l);
				}
			});
		});
	}
}
